<rss version="2.0" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
    <channel>
        <title>Global Internet Business Solutions ~ GIBS</title> 
        <link>https://gibs.com</link> 
        <description>RSS feeds for Global Internet Business Solutions ~ GIBS</description> 
        <ttl>60</ttl> <item>
    <comments>https://gibs.com/Support/Knowledge-Base/ID/342/GIBS_IP-Guard_Module_for_Oqtane#Comments</comments> 
    <slash:comments>0</slash:comments> 
    <wfw:commentRss>https://gibs.com/DesktopModules/DnnForge%20-%20NewsArticles/RssComments.aspx?TabID=51&amp;ModuleID=411&amp;ArticleID=342</wfw:commentRss> 
    <trackback:ping>https://gibs.com:443/DesktopModules/DnnForge%20-%20NewsArticles/Tracking/Trackback.aspx?ArticleID=342&amp;PortalID=0&amp;TabID=51</trackback:ping> 
    <title>GIBS IP-Guard Module for Oqtane</title> 
    <link>https://gibs.com/Support/Knowledge-Base/ID/342/GIBS_IP-Guard_Module_for_Oqtane</link> 
    <description>Protect Oqtane Sites from 404 Probing with GIBS.Module.IPGuard

Public-facing web applications attract constant background noise. Day and night, automated bots scan the internet, probing for exposed admin panels, missing endpoints, common exploits, and stale paths left over from other platforms. Even when those requests fail, they still generate unnecessary server traffic, noisy database logs, and repeated 404 activity.

Think of it like a malicious actor walking down a street, rattling every single doorknob to see if one accidentally clicks open. A single 404 error from a normal user might just be a broken link or a typo. But 30 extensionless requests for weird paths in less than a minute? That is a doorknob-rattler looking for a way in.

GIBS.Module.IPGuard was built to solve this exact problem in a practical, automated way for the Oqtane ecosystem. Instead of just letting your server endlessly log those misses, IPGuard turns 404 traffic into an active security signal. It watches for repeated failures, counts them by client IP address, and automatically blocks the offenders before they can do any harm.


Core Capabilities

1. Automatic IP Blocking &amp;amp; Enforcement

The module tracks qualifying 404 requests in real time. When an IP address hits your designated threshold inside the configured time window, it is instantly added to the global block list. Future requests from that IP are cut off immediately at the middleware level, returning an HTTP 403 Forbidden (Access Denied) response before they ever touch your application pipeline.

2. Built for Modern Architecture (X-Forwarded-For Support)

Many production Oqtane sites sit safely behind a reverse proxy, load balancer, or Content Delivery Network (like Cloudflare or AWS CloudFront). Standard IP tracking often makes the mistake of logging the proxy&amp;#39;s IP instead of the visitor&amp;#39;s. IPGuard handles this defensively: it smartly inspects the X-Forwarded-For header first, ensuring you block the actual malicious actor rather than your own upstream infrastructure.

3. Bootstrap 5 Administrator Dashboard

Managing your site&amp;#39;s security shouldn&amp;#39;t require digging through complex database tables. IPGuard features a clean, native administrative UI that is fully Bootstrap 5 ready. It integrates seamlessly with modern Oqtane themes to give you perfect visibility across desktop and mobile devices.

Through the control panel, administrators have two core views:


 Blocked IP Addresses: View the blocked date, total error counts, specific reasons, and automatic country lookups.
 Recent 404 Attempts: Keep an eye on incoming traffic by reviewing the exact URLs being requested, timestamps, and originating IPs.


4. Manual Overrides &amp;amp; Granular Control

Automation is great, but control is better. From the dashboard, you can manually block or unblock IPs, clear out recent logs, or use the &amp;quot;Add To Blocked&amp;quot; shortcut to instantly ban a suspicious IP with a single click. Doing so automatically queries the country data, sets the audit trail to a manual block, and cleanly scrubs that IP&amp;#39;s history from your active 404 tracking tables.


Best Practice Configurations

To help you get started, we recommend the following baseline settings for a balance between tight security and user experience:



 
  
   Setting
   Recommended Value
   Purpose
  
 
 
  
   404 Threshold
   15&amp;ndash;20 attempts
   High enough to ensure regular users with broken image links won&amp;#39;t trigger a false positive, but low enough to swiftly trap a rapid bot scan.
  
  
   Block Window
   1&amp;ndash;2 Hours
   A rolling lookback window ensures that slow-probing bots are caught over time without permanently hoarding unnecessary tracking data.
  
  
   Exclude Reserved Routes
   Enabled
   Prevents core internal Oqtane routes (like /admin) or standard framework paths (like /_blazor and /_framework) from throwing accidental flags.
  
 




Built for Real-World Hosting

Oqtane environments excel at multi-tenancy, and IPGuard was engineered with that in mind. Settings are optimized at the host level, while blocked records and error attempts are stored globally at the tenant database level rather than fragmenting across individual site instances.

Furthermore, the module includes robust runtime safety nets. If tenant persistence isn&amp;#39;t fully ready during an installation or a sudden startup gap, IPGuard safely loops past the request pipeline with a warning rather than breaking your live site.

Final Thoughts

GIBS.Module.IPGuard isn&amp;#39;t designed to replace an enterprise-grade upstream Web Application Firewall (WAF). Instead, it provides a highly focused, lightweight, and deeply integrated layer of application defense that slashes log noise and stops automated discovery scripts right in their tracks.

If you are running Oqtane in production, it offers the ideal balance of background automation, administrative visibility, and native Bootstrap 5 performance.



Ready to secure your Oqtane ecosystem?

Download the GIBS IP-Guard Module&amp;nbsp;Contact Our Dev Team

</description> 
    <dc:creator>Webmaster</dc:creator> 
    <pubDate>Mon, 19 Oct 2026 09:27:00 GMT</pubDate> 
    <guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:342</guid> 
    
</item>
<item>
    <comments>https://gibs.com/Support/Knowledge-Base/ID/340/How_to_check_net_runtime_version_in_Azure_App_Service#Comments</comments> 
    <slash:comments>0</slash:comments> 
    <wfw:commentRss>https://gibs.com/DesktopModules/DnnForge%20-%20NewsArticles/RssComments.aspx?TabID=51&amp;ModuleID=411&amp;ArticleID=340</wfw:commentRss> 
    <trackback:ping>https://gibs.com:443/DesktopModules/DnnForge%20-%20NewsArticles/Tracking/Trackback.aspx?ArticleID=340&amp;PortalID=0&amp;TabID=51</trackback:ping> 
    <title>How to check .net runtime version in Azure App Service</title> 
    <link>https://gibs.com/Support/Knowledge-Base/ID/340/How_to_check_net_runtime_version_in_Azure_App_Service</link> 
    <description>Using the Azure Portal


 Sign in to the&amp;nbsp;Azure portal.
 Navigate to your&amp;nbsp;App Service&amp;nbsp;and select it.
 In the left navigation menu, under&amp;nbsp;Settings, select&amp;nbsp;Configuration.
 Select the&amp;nbsp;General settings&amp;nbsp;tab.
 In the&amp;nbsp;Stack settings&amp;nbsp;section, you will see the&amp;nbsp;Runtime stack&amp;nbsp;and the specific&amp;nbsp;.NET version&amp;nbsp;being used.&amp;nbsp;


Using the Kudu Console (Advanced Tools)

The Kudu console provides direct access to the underlying environment and installed runtimes.&amp;nbsp;


 
 
  In the Azure portal, navigate to your App Service.
  Under&amp;nbsp;Development Tools, select&amp;nbsp;Advanced Tools, then select&amp;nbsp;Go.
  In the Kudu services window, select&amp;nbsp;Debug console&amp;nbsp;and choose either&amp;nbsp;CMD&amp;nbsp;or&amp;nbsp;PowerShell.
  Run the appropriate command in the console:
  
   For&amp;nbsp;.NET Core&amp;nbsp;and&amp;nbsp;.NET 5+, run&amp;nbsp;dotnet --list-runtimes&amp;nbsp;or&amp;nbsp;dotnet --info&amp;nbsp;to see all installed versions.
  
  
 
 

</description> 
    <dc:creator>Webmaster</dc:creator> 
    <pubDate>Wed, 17 Dec 2025 16:56:00 GMT</pubDate> 
    <guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:340</guid> 
    
</item>
<item>
    <comments>https://gibs.com/Support/Knowledge-Base/ID/337/Getting_AliasId_TenantId_and_SiteId_in_Oqtane#Comments</comments> 
    <slash:comments>0</slash:comments> 
    <wfw:commentRss>https://gibs.com/DesktopModules/DnnForge%20-%20NewsArticles/RssComments.aspx?TabID=51&amp;ModuleID=411&amp;ArticleID=337</wfw:commentRss> 
    <trackback:ping>https://gibs.com:443/DesktopModules/DnnForge%20-%20NewsArticles/Tracking/Trackback.aspx?ArticleID=337&amp;PortalID=0&amp;TabID=51</trackback:ping> 
    <title>Getting AliasId, TenantId and SiteId in Oqtane</title> 
    <link>https://gibs.com/Support/Knowledge-Base/ID/337/Getting_AliasId_TenantId_and_SiteId_in_Oqtane</link> 
    <description>private string myaid = &amp;quot;&amp;quot;;

&amp;nbsp;protected override async Task OnInitializedAsync()
&amp;nbsp;{
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; try
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {

var _aliasid = PageState.Alias.AliasId;
var _tenantId = PageState.Alias.TenantId;
var _siteId = PageState.Alias.SiteId;

&amp;nbsp;myaid = &amp;quot;AliasId: &amp;quot; + _aliasid.ToString() + &amp;quot; TenantId: &amp;quot; + _tenantId.ToString() + &amp;quot; SiteId: &amp;quot; + _siteId.ToString();

}

catch (Exception ex)
{
&amp;nbsp; &amp;nbsp; await logger.LogError(ex, &amp;quot;Error Loading Business Directory Type {Error}&amp;quot;, ex.Message);
&amp;nbsp; &amp;nbsp; AddModuleMessage(Localizer[&amp;quot;Message.LoadError&amp;quot;], MessageType.Error);
}

}
</description> 
    <dc:creator>Webmaster</dc:creator> 
    <pubDate>Sun, 29 Jun 2025 10:28:00 GMT</pubDate> 
    <guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:337</guid> 
    
</item>
<item>
    <comments>https://gibs.com/Support/Knowledge-Base/ID/336/Heres_how_to_implement_Database_calls_in_Oqtane#Comments</comments> 
    <slash:comments>0</slash:comments> 
    <wfw:commentRss>https://gibs.com/DesktopModules/DnnForge%20-%20NewsArticles/RssComments.aspx?TabID=51&amp;ModuleID=411&amp;ArticleID=336</wfw:commentRss> 
    <trackback:ping>https://gibs.com:443/DesktopModules/DnnForge%20-%20NewsArticles/Tracking/Trackback.aspx?ArticleID=336&amp;PortalID=0&amp;TabID=51</trackback:ping> 
    <title>Here’s how to implement Database calls in Oqtane</title> 
    <link>https://gibs.com/Support/Knowledge-Base/ID/336/Heres_how_to_implement_Database_calls_in_Oqtane</link> 
    <description>1. Add Repository Method
Project: Server
File: Server\Repository\BusinessCompanyRepository.cs
Add this method:
public async Task&lt;List&lt;BusinessCompany&gt;&gt; GetBusinessCompaniesByIsNewItemAsync(int moduleId)
{
&nbsp; &nbsp; using var db = _factory.CreateDbContext();
&nbsp; &nbsp; return await db.BusinessCompany
&nbsp; &nbsp; &nbsp; &nbsp; .Where(c =&gt; c.ModuleId == moduleId &amp;&amp; c.IsNewItem)
&nbsp; &nbsp; &nbsp; &nbsp; .OrderBy(c =&gt; c.SortOrder)
&nbsp; &nbsp; &nbsp; &nbsp; .AsNoTracking()
&nbsp; &nbsp; &nbsp; &nbsp; .ToListAsync();
}

&nbsp;

2. Add to Repository Interface
Project: Server
File: Server\Repository\IBusinessCompanyRepository.cs
Add:

Task&lt;List&lt;BusinessCompany&gt;&gt; GetBusinessCompaniesByIsNewItemAsync(int moduleId);

&nbsp;

3. Add to Shared Service Interface
Project: Shared
File: Shared\Interfaces\IBusinessCompanyService.cs
Add:
Task&lt;List&lt;Models.BusinessCompany&gt;&gt; GetBusinessCompaniesByIsNewItemAsync(int moduleId);

&nbsp;

4. Add to Server Service Implementation
Project: Server
File: Server\Services\BusinessCompanyService.cs
Add:
public async Task&lt;List&lt;BusinessCompany&gt;&gt; GetBusinessCompaniesByIsNewItemAsync(int moduleId)
{
&nbsp; &nbsp; return await _repository.GetBusinessCompaniesByIsNewItemAsync(moduleId);
}

&nbsp;

5. Add API Endpoint
Project: Server
File: Server\Controllers\BusinessCompanyController.cs
Add:
[HttpGet(&quot;isnew/{moduleId}&quot;)]
public async Task&lt;ActionResult&lt;List&lt;BusinessCompany&gt;&gt;&gt; GetBusinessCompaniesByIsNewItem(int moduleId)
{
&nbsp; &nbsp; var companies = await _businessCompanyRepository.GetBusinessCompaniesByIsNewItemAsync(moduleId);
&nbsp; &nbsp; return Ok(companies);
}

&nbsp;

6. Add to Client Service
Project: Client
File: Client\Services\BusinessCompanyService.cs
Add:
public async Task&lt;List&lt;Models.BusinessCompany&gt;&gt; GetBusinessCompaniesByIsNewItemAsync(int moduleId)
{
&nbsp; &nbsp; return await GetJsonAsync&lt;List&lt;Models.BusinessCompany&gt;&gt;(
&nbsp; &nbsp; &nbsp; &nbsp; CreateAuthorizationPolicyUrl($&quot;{Apiurl}/isnew/{moduleId}&quot;, EntityNames.Module, moduleId),
&nbsp; &nbsp; &nbsp; &nbsp; Enumerable.Empty&lt;Models.BusinessCompany&gt;().ToList());
}

&nbsp;

7. Use in Index.razor
Project: Client
File: Client\Modules\GIBS.Module.BusinessDirectory\Index.razor
a. In your @code block, load the list if no type is selected:
&nbsp;

private List&lt;BusinessCompany&gt; _newCompanies;

protected override async Task OnInitializedAsync()
{
&nbsp; &nbsp; try
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; ParentItems = BuildTree(await BusinessDirectoryService.GetBusinessDirectorysAsync(ModuleState.ModuleId));
&nbsp; &nbsp; &nbsp; &nbsp; _BusinessDirectorys = await BusinessDirectoryService.GetBusinessDirectorysAsync(ModuleState.ModuleId);

&nbsp; &nbsp; &nbsp; &nbsp; if (PageState.QueryString.ContainsKey(&quot;typeId&quot;) &amp;&amp; int.TryParse(PageState.QueryString[&quot;typeId&quot;], out var typeId))
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _selectedTypeId = typeId;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _companies = await BusinessCompanyService.GetBusinessCompaniesByTypeAsync(typeId, ModuleState.ModuleId);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; else
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _selectedTypeId = null;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _companies = null;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _newCompanies = await BusinessCompanyService.GetBusinessCompaniesByIsNewItemAsync(ModuleState.ModuleId);
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
&nbsp; &nbsp; catch (Exception ex)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; await logger.LogError(ex, &quot;Error Loading Business Directory Type {Error}&quot;, ex.Message);
&nbsp; &nbsp; &nbsp; &nbsp; AddModuleMessage(Localizer[&quot;Message.LoadError&quot;], MessageType.Error);
&nbsp; &nbsp; }
}

b. In your markup, display the cards when no type is selected:

@if (!_selectedTypeId.HasValue)
{
&nbsp; &nbsp; &lt;div class=&quot;row&quot;&gt;
&nbsp; &nbsp; &nbsp; &nbsp; @if (_newCompanies == null)
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;col-12&quot;&gt;&lt;em&gt;@Localizer[&quot;LoadingCompanies&quot;]&lt;/em&gt;&lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; else if (_newCompanies.Count == 0)
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;col-12&quot;&gt;@Localizer[&quot;NoCompaniesFound&quot;]&lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; else
&nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @foreach (var company in _newCompanies)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;col-md-4 mb-3&quot;&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;card&quot;&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;card-body&quot;&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;h5 class=&quot;card-title&quot;&gt;@company.CompanyName&lt;/h5&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @if (!string.IsNullOrWhiteSpace(company.Address))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;card-text&quot;&gt;@company.Address, @company.City, @company.State @company.ZipCode&lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @if (!string.IsNullOrWhiteSpace(company.Phone))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;card-text&quot;&gt;@company.Phone&lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @if (!string.IsNullOrWhiteSpace(company.Website))
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class=&quot;card-text&quot;&gt;&lt;a href=&quot;@company.Website&quot; target=&quot;_blank&quot;&gt;@company.Website&lt;/a&gt;&lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &lt;/div&gt;
}
</description> 
    <dc:creator>Webmaster</dc:creator> 
    <pubDate>Thu, 26 Jun 2025 15:45:00 GMT</pubDate> 
    <guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:336</guid> 
    
</item>

    </channel>
</rss>